package com.reggie.setmeal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.category.entity.Category;
import com.reggie.category.service.CategoryService;
import com.reggie.configuration.common.Result;
import com.reggie.configuration.myException.CustomException;
import com.reggie.setmeal.dao.SetmealDao;
import com.reggie.setmeal.entity.Setmeal;
import com.reggie.setmeal.entity.SetmealDish;
import com.reggie.setmeal.entity.dto.SetmealDTO;
import com.reggie.setmeal.service.SetmealDishService;
import com.reggie.setmeal.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceimpl extends ServiceImpl<SetmealDao, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDao dao;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService dishService;

    //这个对象就是我们的Redis缓存
    @Autowired
    private CacheManager cacheManager;

    /**
     * 修改和储存套餐信息
     * @param dto
     */
    @Override
    @Transactional
    public SetmealDTO saveWithDish(SetmealDTO dto) {
        //单独储存套餐信息
        this.saveOrUpdate(dto);

        //获取菜品信息
        List<SetmealDish> setmealDishes = dto.getSetmealDishes();

        //给上面获取到的菜品信息赋上套餐的值
        List<SetmealDish> collect = setmealDishes.stream()
                .peek(item -> item.setSetmealId(dto.getId()))
                .collect(Collectors.toList());

        //saveBatch可以储存一个集合
        dishService.saveBatch(collect);
        return dto;
    }

    @Override
    public Result<IPage> selectByPage(int page, int pageSize, String name) {
        IPage<Setmeal> pageInfo = new Page(page, pageSize);

        QueryWrapper<Setmeal> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Setmeal> lambda = queryWrapper.lambda();
        lambda.like(name != null, Setmeal::getName, name);
        IPage<Setmeal> result = this.page(pageInfo, queryWrapper);

        //等会用来将pageInfo里的东西拷贝过来
        IPage<SetmealDTO> dtoiPage = new Page<>();

        BeanUtils.copyProperties(result, dtoiPage, "records");

        List<Setmeal> records = pageInfo.getRecords();

        List<SetmealDTO> collect = records.stream().map(item -> {
            SetmealDTO setmealDTO = new SetmealDTO();
            //对象拷贝
            BeanUtils.copyProperties(item, setmealDTO);
            //对象分类ID
            Long categoryId = item.getCategoryId();

            Category byID = categoryService.getByID(categoryId);

            if (byID != null) {
                setmealDTO.setCategoryName(byID.getName());
            }
            return setmealDTO;
        }).collect(Collectors.toList());

        dtoiPage.setRecords(collect);
        return Result.success(dtoiPage);
    }

    /**
     * 修改套餐信息对数据回显
     * @param id
     * @return
     */
    @Override
    public SetmealDTO selectByID(Long id) {
        //先创建一个dto对象，用来返回到前端
        SetmealDTO dto = new SetmealDTO();
        //获得到套餐的数据，等会拷贝到dto里
        Setmeal SetmealById = this.getById(id);
        //获取分类到名字，等会也拷贝到dto里
        Category CategoryByID = categoryService.getByID(SetmealById.getCategoryId());
        dto.setCategoryName(CategoryByID.getName());

        QueryWrapper<SetmealDish> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SetmealDish> lambda = queryWrapper.lambda();

        lambda.eq(SetmealDish::getSetmealId, id);

        BeanUtils.copyProperties(SetmealById, dto);

        dto.setSetmealDishes(dishService.list(queryWrapper));

        return dto;
    }

    /**
     * 删除套餐信息：要在停售状态下
     * @param longIDs
     *
     * CacheEvict注解是删除Redis缓存的数据
     */
    @CacheEvict(value = "setmealCache",key = "#longIDs")
    @Override
    public void deleteByIDs(List<Long> longIDs) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //判断是否为停售状态
        queryWrapper.eq(Setmeal::getStatus, 1);
        queryWrapper.in(Setmeal::getId,longIDs);

        int count = this.count(queryWrapper);

        if (count == 0) {
            this.removeByIds(longIDs);
        } else {
            throw new CustomException("有套餐正在售卖中，不能删除");
        }

    }

    /**
     * 停售或启售套餐
     * @param status
     * @param longIDs
     */
    @Override
    public void stopSellSetmeal(int status, List<Long> longIDs) {
        QueryWrapper<Setmeal> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<Setmeal> lambda = queryWrapper.lambda();
        lambda.in(Setmeal::getId, longIDs);

        List<Setmeal> list = this.list(queryWrapper);

        for (Setmeal setmeal : list) {
            dao.updateStatus(setmeal.getId(), status);
        }
    }

    /**
     *
     * @param setmealId
     * @return
     */
    @Override
    public String selectSetmealNameByID(Long setmealId) {
       Setmeal setmeal = dao.selectSetmealNameById(setmealId);
        if (setmeal != null){
            return setmeal.getName();
        }
        return null;
    }


}
